/* 该程序中的makepair函数将两个路径名作为参数，并用这两个路径名创建了两个命名管道
 * 如果成功，makepair函数就会返回0，如果失败，则makepair函数就会返回-1，并设置errno
 * 该函数在创建这两个 管道的过程中会阻塞所有进程，以确保在出现错误时能够释放这两个管道
 * 该函数在返回前会恢复原始的信号掩码
 * */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>

#define R_MODE (S_IRUSR | S_IRGRP | S_IROTH)
#define W_MODE (S_IWUSR | S_IWGRP | S_IWOTH)
#define RW_MODE (R_MODE | W_MODE)

int makepair(char *pipe1, char *pipe2) {
    sigset_t blockmask, oldmask;
    int returncode = 0;

    if (sigfillset(&blockmask) == -1) {
        return -1;
    }
    fprintf(stderr, "fill all signal to sigset\n");

    if (sigprocmask(SIG_SETMASK, &blockmask, &oldmask) == -1) {
        return -1;
    }

    if ( ((mkfifo(pipe1, RW_MODE) == -1) && (errno != EEXIST)) ||
         ((mkfifo(pipe2, RW_MODE) == -1) && (errno != EEXIST)) ) {
             fprintf(stderr, "Failed to make fifo, the fifo is existed, errno = %d\n", errno);
             returncode = errno;
             unlink(pipe1);
             unlink(pipe2);
    }

    if ( (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) && !returncode ) {
        returncode = errno;
        fprintf(stderr, "Failed to fill the oldmask\n");
    }
    
    if (returncode) {
        fprintf(stderr, "returncode = %d\n", returncode);
        errno = returncode;
        return -1;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s FIFO1 FIFO2\n", argv[0]);
        return -1;
    }

    if (makepair(argv[1], argv[2]) == 0) {
        fprintf(stderr, "makepair successful!\n");
    } else {
        fprintf(stderr, "Failed to makepair, errno = %d\n", errno);
    }

    fprintf(stderr, "---------------------------------\n");

    if (makepair(argv[1], argv[2]) == 0) {
        fprintf(stderr, "makepair successful!\n");
    } else {
        fprintf(stderr, "Failed to makepair, errno = %d\n", errno);
    }

    return 0;
}